package com.gl.basis.mongodb.config;


import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;

@Configuration
@ConditionalOnClass(MongoClient.class)
@EnableConfigurationProperties(MongoOptionProperties.class)
@ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDbFactory")
public class MongoPlusAutoConfiguration {
    private static final Logger log = LoggerFactory.getLogger(MongoPlusAutoConfiguration.class);

	@Autowired
	private MongoClientOptions mongoClientOptions;

	@Bean
	public MongoClientOptions mongoClientOptions(MongoOptionProperties mongoOptionProperties) {
		if (mongoOptionProperties == null) {
			return new MongoClientOptions.Builder().build();
		}

		return new MongoClientOptions.Builder().minConnectionsPerHost(mongoOptionProperties.getMinConnectionPerHost())
				.connectionsPerHost(mongoOptionProperties.getMaxConnectionPerHost())
				.threadsAllowedToBlockForConnectionMultiplier(
						mongoOptionProperties.getThreadsAllowedToBlockForConnectionMultiplier())
				.serverSelectionTimeout(mongoOptionProperties.getServerSelectionTimeout())
				.maxWaitTime(mongoOptionProperties.getMaxWaitTime())
				.maxConnectionIdleTime(mongoOptionProperties.getMaxConnectionIdleTime())
				.maxConnectionLifeTime(mongoOptionProperties.getMaxConnectionLifeTime())
				.connectTimeout(mongoOptionProperties.getConnectTimeout())
				.socketTimeout(mongoOptionProperties.getSocketTimeout())
				.socketKeepAlive(mongoOptionProperties.getSocketKeepAlive())
				.sslEnabled(mongoOptionProperties.getSslEnabled())
				.sslInvalidHostNameAllowed(mongoOptionProperties.getSslInvalidHostNameAllowed())
				.alwaysUseMBeans(mongoOptionProperties.getAlwaysUseMBeans())
				.heartbeatFrequency(mongoOptionProperties.getHeartbeatFrequency())
				.minConnectionsPerHost(mongoOptionProperties.getMinConnectionPerHost())
				.heartbeatConnectTimeout(mongoOptionProperties.getHeartbeatConnectTimeout())
				.heartbeatSocketTimeout(mongoOptionProperties.getSocketTimeout())
				.localThreshold(mongoOptionProperties.getLocalThreshold()).build();
	}

	@Bean(name = "mongoDbFactory")
	public MongoTemplate factory(MongoOptionProperties properties) throws UnknownHostException {
		MongoTemplate template;
		try {

			// MongoDB地址列表
			List<ServerAddress> serverAddresses = new ArrayList<ServerAddress>();
			for (String address : properties.getAddress()) {
				String[] hostAndPort = address.split(":");
				String host = hostAndPort[0];
				Integer port = Integer.parseInt(hostAndPort[1]);
				ServerAddress serverAddress = new ServerAddress(host, port);
				serverAddresses.add(serverAddress);
			}

			// 创建非认证客户端
			MongoClient mongoClient = new MongoClient(serverAddresses, mongoClientOptions);

			// 创建MongoDbFactory
			MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClient, properties.getDatabase());
			 log.info("msg1=初始化 Mongo 成功,uri,配置参数,,glUri={},,options={}", properties.getAddress(),
	            		properties);
			template = new MongoTemplate(mongoDbFactory);
		} catch (Exception e) {
			log.error("exception=" + e.getMessage() + ",,msg1=初始化 Mongo 失败,,StackTrace=", e);
			throw e;
		}
		return template;
	}

	@Bean(name = "mongoDbFactory")
	public MongoTemplate getMongoTemplate(MongoDbFactory mongoDbFactory) {
		return new MongoTemplate(mongoDbFactory);
	}
}